#!/bin/bash
#
# 金牛座数据表文档生成系统 - 命令行工具
# 
# 此脚本集成了所有文档生成功能，可以通过不同选项执行
#

# 当前脚本所在目录（用于定位其他脚本）
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BASE_DIR="$(dirname "$SCRIPT_DIR")"

# 加载环境配置文件
CONFIG_FILE="$SCRIPT_DIR/env.config"
if [ ! -f "$CONFIG_FILE" ]; then
  echo "错误: 找不到配置文件 $CONFIG_FILE"
  exit 1
fi

# 加载配置文件
echo "正在加载配置文件: $CONFIG_FILE"
# 导入配置变量
source "$CONFIG_FILE"
echo "配置文件加载成功"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色

# 默认参数
OFFLINE_MODE=false
USE_MOCK_TOKEN=false
REFRESH_TOKEN=false
SKIP_CONFIG=false
EXPORT_CSV=false
COMMAND="all"
TARGET_TABLE=""
CONFIG_JSON=""
# 默认使用配置文件中的Schema名称
SCHEMA_NAME="$SCHEMA_NAME"
# API日志记录参数
ENABLE_API_LOGGING=false
CLEAR_API_LOGS=false

# 显示当前环境配置
function show_config {
    echo -e "${BLUE}当前环境配置:${NC}"
    echo -e "API地址: ${YELLOW}$AUTO_API_BASE_URL${NC}"
    echo -e "项目ID: ${YELLOW}$PROJECT_ID${NC}"
    echo -e "Schema名称: ${YELLOW}$SCHEMA_NAME${NC}"
    echo -e "输出基础目录: ${YELLOW}$OUTPUT_BASE_DIR${NC}"
    echo -e "配置文件: ${YELLOW}$CONFIG_FILE${NC}"
    echo -e "API日志记录: ${YELLOW}$([ "$ENABLE_API_LOGGING" = true ] && echo "启用" || echo "禁用")${NC}"
    echo ""
}

# 打印帮助信息
function print_help {
    echo -e "${BLUE}金牛座数据表文档生成系统 - 命令行工具${NC}"
    echo ""
    echo "用法: $0 [命令] [选项] [参数]"
    echo ""
    echo "命令:"
    echo "  all                     执行完整的文档生成流程（默认）"
    echo "  config                  只生成配置文件"
    echo "  docs                    只生成文档和类型定义"
    echo "  csv                     导出表数据为CSV"
    echo "  update-table <表名> <配置JSON>  更新单个表的配置"
    echo "  update-default <配置JSON>      更新默认配置"
    echo "  list-tables [schema名称]      测试获取数据库表列表"
    echo "  test-api                测试API连接"
    echo "  show-config             显示当前环境配置"
    echo "  clear-logs              清除所有日志文件"
    echo "  help                    显示帮助信息"
    echo ""
    echo "选项:"
    echo "  -o, --offline           离线模式，不连接API"
    echo "  -m, --mock-token        使用模拟token"
    echo "  -r, --refresh-token     强制刷新token"
    echo "  -s, --skip-config       跳过配置生成步骤"
    echo "  -c, --csv               导出CSV数据"
    echo "  -h, --help              显示帮助信息"
    echo "  --schema <名称>         指定数据库schema名称"
    echo "  --log-api               启用API请求和响应日志记录"
    echo "  --clear-api-logs        清除API日志文件"
    echo ""
    echo "示例:"
    echo "  $0                       # 执行完整流程"
    echo "  $0 all -o -m             # 离线模式执行完整流程"
    echo "  $0 all --log-api         # 执行完整流程并记录API日志"
    echo "  $0 config                # 只生成配置文件"
    echo "  $0 docs -r               # 生成文档并强制刷新token"
    echo "  $0 list-tables           # 测试获取数据库表列表"
    echo "  $0 test-api              # 测试API连接"
    echo "  $0 test-api --log-api    # 测试API连接并记录日志"
    echo "  $0 show-config           # 显示当前环境配置"
    echo "  $0 clear-logs            # 清除所有日志文件"
    echo "  $0 list-tables --schema myschema  # 指定schema获取表列表"
    echo "  $0 update-table ods_ng_pipline_attr '{\"enabled\":true}'"
    echo "                          # 更新表的配置"
    echo ""
    
    # 显示当前环境配置
    show_config
}

# 执行流程
function execute_all {
    echo -e "${BLUE}=== 开始执行完整流程 ===${NC}"
    
    # 构建一键执行命令
    CMD="node $SCRIPT_DIR/generate-all.js"
    
    # 添加参数
    if [ "$OFFLINE_MODE" = true ]; then
        CMD="$CMD --offline"
    fi
    
    if [ "$USE_MOCK_TOKEN" = true ]; then
        CMD="$CMD --mock-token"
    fi
    
    if [ "$REFRESH_TOKEN" = true ]; then
        CMD="$CMD --refresh-token"
    fi
    
    if [ "$SKIP_CONFIG" = true ]; then
        CMD="$CMD --skip-config"
    fi
    
    if [ "$EXPORT_CSV" = true ]; then
        CMD="$CMD --export-csv"
    fi
    
    if [ -n "$SCHEMA_NAME" ]; then
        CMD="$CMD --schema $SCHEMA_NAME"
    fi
    
    if [ "$ENABLE_API_LOGGING" = true ]; then
        CMD="$CMD --log-api"
    fi
    
    if [ "$CLEAR_API_LOGS" = true ]; then
        CMD="$CMD --clear-api-logs"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}完整流程执行成功！${NC}"
    else
        echo -e "${RED}执行失败，请查看日志获取详细信息${NC}"
        exit 1
    fi
}

# 只生成配置
function execute_config {
    echo -e "${BLUE}=== 开始生成配置文件 ===${NC}"
    
    # 构建命令
    CMD="node $SCRIPT_DIR/generateTableConfig.js generate"
    
    # 添加参数
    if [ "$OFFLINE_MODE" = true ]; then
        CMD="$CMD --offline"
    fi
    
    if [ "$USE_MOCK_TOKEN" = true ]; then
        CMD="$CMD --mock-token"
    fi
    
    if [ -n "$SCHEMA_NAME" ]; then
        CMD="$CMD --schema $SCHEMA_NAME"
    fi
    
    if [ "$ENABLE_API_LOGGING" = true ]; then
        CMD="$CMD --log-api"
    fi
    
    if [ "$CLEAR_API_LOGS" = true ]; then
        CMD="$CMD --clear-api-logs"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}配置文件生成成功！${NC}"
    else
        echo -e "${RED}配置文件生成失败，请查看日志获取详细信息${NC}"
        exit 1
    fi
}

# 只生成文档
function execute_docs {
    echo -e "${BLUE}=== 开始生成文档和类型定义 ===${NC}"
    
    # 构建命令
    CMD="node $SCRIPT_DIR/generateTableDocs.js"
    
    # 添加参数
    if [ "$OFFLINE_MODE" = true ]; then
        CMD="$CMD --offline"
    fi
    
    if [ "$USE_MOCK_TOKEN" = true ]; then
        CMD="$CMD --mock-token"
    fi
    
    if [ "$REFRESH_TOKEN" = true ]; then
        CMD="$CMD --refresh-token"
    fi
    
    if [ -n "$SCHEMA_NAME" ]; then
        CMD="$CMD --schema $SCHEMA_NAME"
    fi
    
    if [ "$ENABLE_API_LOGGING" = true ]; then
        CMD="$CMD --log-api"
    fi
    
    if [ "$CLEAR_API_LOGS" = true ]; then
        CMD="$CMD --clear-api-logs"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}文档生成成功！${NC}"
    else
        echo -e "${RED}文档生成失败，请查看日志获取详细信息${NC}"
        exit 1
    fi
}

# 导出CSV
function execute_csv {
    echo -e "${BLUE}=== 开始导出表数据为CSV ===${NC}"
    
    # 确保先生成了文档
    if [ ! -d "$BASE_DIR/raw-data/metadata" ]; then
        echo -e "${YELLOW}警告: 没有找到元数据目录，请先生成文档${NC}"
        
        read -p "是否先生成文档? [Y/n] " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
            execute_docs
        else
            echo -e "${RED}无法导出CSV，缺少必要的元数据${NC}"
            exit 1
        fi
    fi
    
    # 构建一键执行命令只执行CSV导出部分
    CMD="node $SCRIPT_DIR/generate-all.js --skip-config --export-csv"
    
    # 添加参数
    if [ "$OFFLINE_MODE" = true ]; then
        CMD="$CMD --offline"
    fi
    
    if [ "$USE_MOCK_TOKEN" = true ]; then
        CMD="$CMD --mock-token"
    fi
    
    if [ -n "$SCHEMA_NAME" ]; then
        CMD="$CMD --schema $SCHEMA_NAME"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}CSV导出成功！${NC}"
    else
        echo -e "${RED}CSV导出失败，请查看日志获取详细信息${NC}"
        exit 1
    fi
}

# 更新表配置
function update_table_config {
    if [ -z "$TARGET_TABLE" ]; then
        echo -e "${RED}错误: 缺少表名参数${NC}"
        print_help
        exit 1
    fi
    
    if [ -z "$CONFIG_JSON" ]; then
        echo -e "${RED}错误: 缺少配置JSON参数${NC}"
        print_help
        exit 1
    fi
    
    echo -e "${BLUE}=== 更新表配置 ===${NC}"
    echo -e "表名: ${YELLOW}$TARGET_TABLE${NC}"
    echo -e "配置: ${YELLOW}$CONFIG_JSON${NC}"
    
    # 构建命令
    CMD="node $SCRIPT_DIR/generateTableConfig.js update \"$TARGET_TABLE\" '$CONFIG_JSON'"
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}表配置更新成功！${NC}"
    else
        echo -e "${RED}表配置更新失败${NC}"
        exit 1
    fi
}

# 更新默认配置
function update_default_config {
    if [ -z "$CONFIG_JSON" ]; then
        echo -e "${RED}错误: 缺少配置JSON参数${NC}"
        print_help
        exit 1
    fi
    
    echo -e "${BLUE}=== 更新默认配置 ===${NC}"
    echo -e "配置: ${YELLOW}$CONFIG_JSON${NC}"
    
    # 构建命令
    CMD="node $SCRIPT_DIR/generateTableConfig.js update-default '$CONFIG_JSON'"
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}默认配置更新成功！${NC}"
    else
        echo -e "${RED}默认配置更新失败${NC}"
        exit 1
    fi
}

# 测试获取数据库表列表
function test_list_tables {
    echo -e "${BLUE}=== 测试获取数据库表列表 ===${NC}"
    
    # 创建临时文件用来存放测试脚本
    TEMP_SCRIPT="$SCRIPT_DIR/temp-list-tables.js"
    
    cat > "$TEMP_SCRIPT" << 'EOF'
/**
 * 测试获取数据库表列表的工具
 */
const http = require('http');
const fs = require('fs');
const path = require('path');

// 获取命令行参数
const args = process.argv.slice(2);
const useMockToken = args.includes('--mock-token');
const schemaIndex = args.indexOf('--schema');
const schemaName = schemaIndex !== -1 && args[schemaIndex + 1] ? args[schemaIndex + 1] : process.env.SCHEMA_NAME;

// 从环境变量获取配置
const AUTO_API_BASE_URL = process.env.AUTO_API_BASE_URL;
const PROJECT_ID = process.env.PROJECT_ID;
const MOCK_TOKEN = 'mock-token-for-testing';

console.log(`API基础URL: ${AUTO_API_BASE_URL}`);
console.log(`项目ID: ${PROJECT_ID}`);
console.log(`Schema名称: ${schemaName}`);
console.log(`使用模拟Token: ${useMockToken}`);

// 输出目录
const OUTPUT_DIR = path.resolve(__dirname, '../raw-data/metadata');
if (!fs.existsSync(OUTPUT_DIR)) {
    fs.mkdirSync(OUTPUT_DIR, { recursive: true });
    console.log(`创建输出目录: ${OUTPUT_DIR}`);
}

/**
 * 发送HTTP请求
 */
async function fetchApi(url, method, body, headers = {}) {
    console.log(`发起API请求: ${method} ${url}`);
    
    return new Promise((resolve, reject) => {
        try {
            // 解析URL
            const urlObj = new URL(url);
            
            // 请求选项
            const options = {
                hostname: urlObj.hostname,
                port: urlObj.port || 80,
                path: urlObj.pathname + urlObj.search,
                method: method,
                headers: {
                    'Content-Type': 'application/json',
                    ...headers
                }
            };
            
            // 创建请求
            const req = http.request(options, (res) => {
                let data = '';
                
                // 接收数据
                res.on('data', (chunk) => {
                    data += chunk;
                });
                
                // 数据接收完成
                res.on('end', () => {
                    try {
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            const parsedData = JSON.parse(data);
                            console.log(`API请求成功: ${method} ${url} (状态码: ${res.statusCode})`);
                            resolve(parsedData);
                        } else {
                            console.error(`API请求失败: ${method} ${url} (状态码: ${res.statusCode})`);
                            console.error(`响应数据: ${data}`);
                            reject(new Error(`HTTP错误: ${res.statusCode}`));
                        }
                    } catch (e) {
                        console.error(`解析响应失败: ${e.message}`);
                        reject(e);
                    }
                });
            });
            
            // 处理错误
            req.on('error', (e) => {
                console.error(`请求失败: ${e.message}`);
                reject(e);
            });
            
            // 发送请求体
            if (body) {
                req.write(JSON.stringify(body));
            }
            
            req.end();
        } catch (e) {
            console.error(`创建请求失败: ${e.message}`);
            reject(e);
        }
    });
}

/**
 * 获取访问令牌
 */
async function getToken() {
    if (useMockToken) {
        console.log('使用模拟token');
        return MOCK_TOKEN;
    }
    
    try {
        console.log('尝试获取token...');
        const response = await fetchApi(`${AUTO_API_BASE_URL}/get_token`, 'POST', {
            project_id: PROJECT_ID
        });
        
        const token = response.data.token;
        console.log(`从API获取token成功: ${token.substring(0, 10)}...(截断)`);
        return token;
    } catch (error) {
        console.error('获取token失败', error);
        throw error;
    }
}

/**
 * 获取表列表
 */
async function getTableList(token) {
    try {
        console.log('尝试获取表列表...');
        console.log(`Schema名称: ${schemaName}`);
        
        const body = {
            tablelist: {
                tableSchema: schemaName
            }
        };
        
        const response = await fetchApi(`${AUTO_API_BASE_URL}/findby?tbName=findbytableSchema`, 'POST', body, 
            { Authorization: token });
        
        console.log(`获取表列表成功，共 ${response.length} 个表`);
        
        // 保存结果
        fs.writeFileSync(
            path.join(OUTPUT_DIR, 'tablelist.json'),
            JSON.stringify(response, null, 2)
        );
        
        return response;
    } catch (error) {
        console.error('获取表列表失败', error);
        return [];
    }
}

/**
 * 主函数
 */
async function main() {
    try {
        console.log('=== 开始测试获取数据库表列表 ===');
        
        // 获取token
        const token = await getToken();
        
        // 获取表列表
        const tables = await getTableList(token);
        
        // 输出汇总
        const summary = {
            timestamp: new Date().toISOString(),
            schemaName: schemaName,
            tables: {
                success: Array.isArray(tables),
                count: Array.isArray(tables) ? tables.length : 0,
                sample: Array.isArray(tables) && tables.length > 0 ? tables.slice(0, 3) : null
            }
        };
        
        fs.writeFileSync(
            path.join(OUTPUT_DIR, 'tables_summary.json'),
            JSON.stringify(summary, null, 2)
        );
        
        console.log('=== 表列表获取测试完成 ===');
        console.log(`结果已保存到: ${path.join(OUTPUT_DIR, 'tables_summary.json')}`);
        
        // 打印结果
        console.log(`获取表列表: ${summary.tables.success ? '成功' : '失败'}, 获取到 ${summary.tables.count} 个表`);
        
        if (summary.tables.count > 0) {
            console.log('前3个表样例:');
            console.log(JSON.stringify(summary.tables.sample, null, 2));
        }
        
    } catch (error) {
        console.error('测试失败', error);
        process.exit(1);
    }
}

// 执行主函数
main();
EOF
    
    # 构建命令
    CMD="node $TEMP_SCRIPT"
    
    # 添加参数
    if [ "$USE_MOCK_TOKEN" = true ]; then
        CMD="$CMD --mock-token"
    fi
    
    if [ -n "$SCHEMA_NAME" ]; then
        CMD="$CMD --schema $SCHEMA_NAME"
    elif [ -n "$1" ]; then
        SCHEMA_NAME="$1"
        CMD="$CMD --schema $SCHEMA_NAME"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    # 检查结果并显示
    RESULT_FILE="$BASE_DIR/raw-data/metadata/tables_summary.json"
    if [ -f "$RESULT_FILE" ]; then
        echo -e "${GREEN}测试完成，结果已保存到: $RESULT_FILE${NC}"
        echo -e "${YELLOW}表列表已保存到: $BASE_DIR/raw-data/metadata/tablelist.json${NC}"
    else
        echo -e "${RED}测试失败，未生成结果文件${NC}"
        exit 1
    fi
    
    # 清除临时脚本
    rm -f "$TEMP_SCRIPT"
}

# 执行API测试
function execute_api_test {
    echo -e "${BLUE}=== 测试API连接 ===${NC}"
    
    # 构建命令
    CMD="node $SCRIPT_DIR/api-test.js"
    
    # 添加日志参数
    if [ "$ENABLE_API_LOGGING" = true ]; then
        CMD="$CMD --log-api"
    fi
    
    if [ "$CLEAR_API_LOGS" = true ]; then
        CMD="$CMD --clear-api-logs"
    fi
    
    # 执行命令
    echo -e "${YELLOW}执行命令: $CMD${NC}"
    eval $CMD
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}API测试完成！${NC}"
        echo -e "请查看测试报告获取详细结果"
        echo -e "测试报告路径: $BASE_DIR/raw-data/api-test/test_report.html"
    else
        echo -e "${RED}API测试失败，请查看日志获取详细信息${NC}"
        exit 1
    fi
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        all|config|docs|csv|update-table|update-default|list-tables|test-api|show-config|clear-logs|help)
            COMMAND="$1"
            shift # 移除命令参数
            
            # 如果是update-table命令，解析额外的参数
            if [ "$COMMAND" = "update-table" ]; then
                if [[ $# -gt 0 ]]; then
                    TARGET_TABLE="$1"
                    shift
                fi
                if [[ $# -gt 0 ]]; then
                    CONFIG_JSON="$1"
                    shift
                fi
            fi
            
            # 如果是update-default命令，解析额外的参数
            if [ "$COMMAND" = "update-default" ]; then
                if [[ $# -gt 0 ]]; then
                    CONFIG_JSON="$1"
                    shift
                fi
            fi
            
            # 如果是list-tables命令，解析额外的schema参数
            if [ "$COMMAND" = "list-tables" ] && [[ $# -gt 0 ]] && [[ $1 != -* ]]; then
                SCHEMA_NAME="$1"
                shift
            fi
            ;;
        -o|--offline)
            OFFLINE_MODE=true
            shift
            ;;
        -m|--mock-token)
            USE_MOCK_TOKEN=true
            shift
            ;;
        -r|--refresh-token)
            REFRESH_TOKEN=true
            shift
            ;;
        -s|--skip-config)
            SKIP_CONFIG=true
            shift
            ;;
        -c|--csv)
            EXPORT_CSV=true
            shift
            ;;
        --schema)
            if [[ $# -gt 1 ]]; then
                SCHEMA_NAME="$2"
                shift 2
            else
                echo -e "${RED}错误: --schema 需要指定值${NC}"
                print_help
                exit 1
            fi
            ;;
        --log-api)
            ENABLE_API_LOGGING=true
            shift
            ;;
        --clear-api-logs)
            CLEAR_API_LOGS=true
            shift
            ;;
        -h|--help)
            print_help
            exit 0
            ;;
        *)
            # 未知参数
            echo -e "${RED}错误: 未知参数 $1${NC}"
            print_help
            exit 1
            ;;
    esac
done

# 根据命令执行相应功能
case $COMMAND in
    all)
        execute_all
        ;;
    config)
        execute_config
        ;;
    docs)
        execute_docs
        ;;
    csv)
        execute_csv
        ;;
    update-table)
        update_table_config
        ;;
    update-default)
        update_default_config
        ;;
    list-tables)
        test_list_tables "$SCHEMA_NAME"
        ;;
    test-api)
        execute_api_test
        ;;
    show-config)
        show_config
        ;;
    clear-logs)
        echo -e "${BLUE}=== 清除所有日志文件 ===${NC}"
        rm -rf "$BASE_DIR/raw-data/api-test"
        rm -rf "$BASE_DIR/raw-data/metadata"
        echo -e "${GREEN}所有日志文件已清除！${NC}"
        ;;
    help)
        print_help
        exit 0
        ;;
    *)
        echo -e "${RED}错误: 未知命令 $COMMAND${NC}"
        print_help
        exit 1
        ;;
esac

exit 0 